﻿/*
 * 设计模式 - 装饰器模式
 * 目的: 重用功能并增加新的功能
 * 不改变对象本身的情况下，增加额外的功能
 */

new Anchor().Inner();

Console.WriteLine();

new Bold(new Anchor()).Inner();

Console.WriteLine();

new Italic(new Bold(new Anchor())).Inner();


abstract class HtmlElement
{
    protected internal abstract void Inner();

    protected abstract string TagName { get; }
}

class Anchor : HtmlElement
{
    protected internal override void Inner()
    {
        Console.Write($"<{TagName}>Anchor</{TagName}>");
    }

    protected override string TagName { get; } = "a";
}

class Paramgraph : HtmlElement
{
    protected internal override void Inner()
    {
        Console.Write($"<{TagName}>Paramgraph</{TagName}>");
    }

    protected override string TagName { get; } = "p";
}

/// <summary>
/// 装饰器
/// </summary>
abstract class Decorator : HtmlElement
{
    private readonly HtmlElement _element;

    public Decorator(HtmlElement element)
    {
        _element = element;
    }

    protected internal override void Inner()
    {
        Console.Write($"<{TagName}>");
        _element.Inner();
        Console.Write($"</{TagName}>");
    }
}


class Italic : Decorator
{
    private readonly HtmlElement _element;

    public Italic(HtmlElement element) : base(element)
    {
        _element = element;
    }

    protected override string TagName { get; } = "i";

    protected internal override void Inner()
    {
        Console.Write($"<<{TagName}>>");
        _element.Inner();
        Console.Write($"<</{TagName}>>");
    }
}


class Bold : Decorator
{
    public Bold(HtmlElement element) : base(element)
    {
    }

    protected override string TagName { get; } = "b";
}